﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Web.Caching;

using Db4objects.Db4o.Config;
using Db4objects.Db4o;
using Db4objects.Db4o.Linq;
using DocManagerORM.ORM;
using System.Data.Metadata.Edm;
using DocManagerORM.Utils;
using System.Data.Objects.DataClasses;
using System.ComponentModel;
using System.Data.Objects;

namespace DocManagerORM.ORM
{
   public  class QueryBase
    {

       public bool UsaDB4Objects { get; set; }

       public IObjectContainer Database { get; set; }

       private static SettingsBaseApplicazione m_SettingsBaseApplicazione_Cache = null;
       
       protected DocManagerDbEntities m_Entity = null;
       public DocManagerDbEntities EntityManager { get { return m_Entity; } }


      private static Lazy<DocManagerDbEntities> m_EntityStatic =
        new Lazy<DocManagerDbEntities>(() => new DocManagerDbEntities());
       
      public static DocManagerDbEntities EntityStatic { get {return m_EntityStatic.Value ;} }



      public QueryBase()
      {
          m_Entity = new DocManagerDbEntities();
          this.tryOpenConn(true);
          
          //creaLayerTabelle();
      }

      public void controllaTempoGenerazione(Action pAzione)
      {
          var stopWatch =  System.Diagnostics.Stopwatch.StartNew();  
          var startManageMemoryBytes = GC.GetTotalMemory(true); //Force GC
          stopWatch.Start();

            pAzione();

          stopWatch.Stop();
          var endManageMemoryBytes = GC.GetTotalMemory(false);
      
      }//fM

      public static void creaLayerTabelle()
      {
          var model = m_EntityStatic.Value.DefaultContainerName;

          var cont = m_EntityStatic.Value.MetadataWorkspace.GetEntityContainer(model,
              System.Data.Metadata.Edm.DataSpace.CSpace);

          var tutteTab = cont.BaseEntitySets.Where(x => x.BuiltInTypeKind == BuiltInTypeKind.EntitySet)
             .OrderBy(x => x.Name).ToList();

          StringBuilder sb = new StringBuilder();
          StringBuilder sb2 = new StringBuilder();

          int conta = 0;
          foreach (var tab in tutteTab)
          {
              sb.Append("case ").Append("\"").Append(tab).Append("\"").AppendLine(":");
              sb.Append("var lista"+ conta +" = ").Append("m_Entity.").Append(tab).AppendLine(".ToList();");
              sb.AppendLine(" lista2 = new BindingListExt<"+ tab +">(lista"+ conta +", ref m_Entity,convalidList);");
              sb.AppendLine("break;");

              conta += 1;
          }

           var str = sb.ToString();
          
          //listRet = new BindingListExt<T>(resList, ref m_Entity);

      }


      public static bool tryOpenConn(bool pMesssaggia,bool pCloseConnection)
      {
          try
          {
              if(m_EntityStatic.Value.Connection.State == System.Data.ConnectionState.Closed)
                m_EntityStatic.Value.Connection.Open();

              if(m_EntityStatic.Value.Connection.State == System.Data.ConnectionState.Closed) 
                  return false ; 

              if(pCloseConnection)m_EntityStatic.Value.Connection.Close(); 

              return true ;
          }
          catch (Exception ex)
          {
              if (pMesssaggia)
                  MessageBox.Show("Errore apertura database, impossibile continuare :\r\n"+ ex.Message,"Avvisi",MessageBoxButton.OK,MessageBoxImage.Warning  );
  
              return false ;
          }
      
      }//fM

       
       public static IList<EntitySetBase> getAllTablesAndViewsInModel(bool pAncheLeViste= false)
       {
           var model = m_EntityStatic.Value.DefaultContainerName;

           var cont = m_EntityStatic.Value.MetadataWorkspace.GetEntityContainer(model, System.Data.Metadata.Edm.DataSpace.CSpace);
          var ret= cont.BaseEntitySets.Where(x => x.BuiltInTypeKind == BuiltInTypeKind.EntitySet)
             .OrderBy(x => x.Name).ToList();

          if (pAncheLeViste)
              return ret;
          else
              return ret.Where(x=> (!x.Name.StartsWith("vw"))).ToList(); 
       
       }//fM

       public IQueryable<Categorie> getRUOLI_Prova()
       {
           var entita = (true? m_Entity.Categorie.AsQueryable<Categorie>(): Database.AsQueryable<Categorie>() );

           var ret = entita.Where(c => c.ID == 1);
           return ret;
                    
        }


       public IQueryable<aspnet_Roles> getRUOLI()
       {
           var ret = m_Entity.aspnet_Roles.Where(c => c.Visible == true);
           return ret;
       }


       public static SettingsBaseApplicazione getSettingsBaseApplicazione()
       {
           try
           {
               if (QueryBase.m_SettingsBaseApplicazione_Cache == null)
                   QueryBase.m_SettingsBaseApplicazione_Cache = EntityStatic.SettingsBaseApplicazione.FirstOrDefault();

               return QueryBase.m_SettingsBaseApplicazione_Cache;
           }
           catch (Exception ex)
           {
               return null;
           }          
       }

      
       public bool tryOpenConn(bool pMessaggia)
       {
           try
           {
               if (m_Entity.Connection.State == System.Data.ConnectionState.Closed)
                   m_Entity.Connection.Open();
               return true;
           }
           catch (Exception ex)
           {
               messaggia("Attenzione : Errore apertura database " + getConnDBName()
                + "  : \r\n" + ex.Message);
               return false;
           }

       }//fM


       protected string getConnDBName()
       {
           try
           {
               return m_Entity.Connection.Database;
           }
           catch (Exception ex)
           {
               return string.Empty;
           }
       
       }//fM

       protected void messaggia(string pMessage)
       {
           MessageBox.Show(pMessage, "Avvisi", MessageBoxButton.OK, MessageBoxImage.Information);
       }//fM

       //non crea entitykey
       public BindingListExt<T> executeQuery<T>(string pTableName) where T : EntityObject, new()
       {
           BindingListExt<T> listRet = null;
           
           var resList = m_Entity.ExecuteStoreQuery<T>("Select * from " + pTableName).ToList();
           
           listRet = new BindingListExt<T>(resList, ref m_Entity);
           return  listRet;

       }//fM

       public BindingListExt<T> executeQueryTable2<T>() where T : EntityObject, new()
       {
           //BindingListExt<T>
           //BindingListExt<T> listRet = null;

           var m_Entity1 = new DocManagerDbEntities();

           T tipo = new T();

           var tabella = tipo.GetType().ToString().Split('.').LastOrDefault();
           //return tabella + " aaa ";

           var resList = m_Entity1.ExecuteStoreQuery<T>("Select * from " + tabella).ToArray();
           
           var listRet = new BindingListExt<T>(resList, ref m_Entity1);
           return listRet;

       }//fM


    }//fC
}
